package org.jeecg.demo.wx.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeecg.dingtalk.api.user.vo.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.demo.wx.convert.TaskTransfer;
import org.jeecg.demo.wx.dto.*;
import org.jeecg.demo.wx.entity.HrmResource;
import org.jeecg.demo.wx.entity.Meeting;
import org.jeecg.demo.wx.entity.RlSchedule;
import org.jeecg.demo.wx.entity.RlTask;
import org.jeecg.demo.wx.enumeration.*;
import org.jeecg.demo.wx.mapper.RlTaskMapper;
import org.jeecg.demo.wx.service.IHrmResourceService;
import org.jeecg.demo.wx.service.IMeetingService;
import org.jeecg.demo.wx.service.IRlScheduleService;
import org.jeecg.demo.wx.service.IRlTaskService;
import org.jeecg.demo.wx.util.PageData;
import org.jeecg.demo.wx.vo.*;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.jeecg.modules.system.service.ISysDepartService;
import org.jeecg.modules.system.service.ISysUserDepartService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.service.impl.ThirdAppDingtalkServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class RlTaskServiceImpl extends ServiceImpl<RlTaskMapper, RlTask> implements IRlTaskService {

    @Autowired
    private IRlScheduleService iRlScheduleService;

    @Autowired
    private ISysUserService iSysUserService;

    @Autowired
    private IMeetingService iMeetingService;


    @Autowired
    private IHrmResourceService iHrmResourceService;

    @Autowired
    private ISysDepartService iSysDepartService;


    @Autowired
    private ISysUserDepartService iSysUserDepartService;

    @Resource
    private SysUserMapper sysUserMapper;

    /**
     * 本地：local minio：minio 阿里：alioss
     */
    @Value(value = "${jeecg.uploadType}")
    private String uploadType;

//    @Value(value = "${jeecg.path.upload}")
    private String uploadpath="";

//    @Value(value = "${jeecg.path.prefix}")
    private String uploadPrefix="";

    /**
     * 对OA系统数据进行轮询添加
     */
//    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    @Scheduled(cron = "0 * * * * ?")
    public void scheduleAddTask() {
        // TODO: 2023/5/30 使用当前时间作为条件对轮询数据做比较处理，大于当前时间才添加数据
        Date start = new Date();
        String today = DateUtil.today();
        log.info("当前时间：" + today + "，开始轮询OA数据");

        // TODO: 2023/5/31 多数据源选择
        List<Meeting> meetings = iMeetingService.queryMeetingData(today);
        meetings.forEach(item -> {
            List<RlTask> taskList = this.lambdaQuery()
                    .eq(RlTask::getOaId, item.getId())
                    .list();
            boolean isExist = taskList.size() > 0;

            if (isExist) {
                RlTask oldTask = taskList.get(0);
                // cancel-1表示取消议程，delFlag-0表示正常进行，两者为此时冲突需要update
                if ("1".equals(item.getCancel()) && "0".equals(oldTask.getDelFlag())) {
                    // 撤回日程和任务
                    this.revokeUserTask(oldTask.getId());
                }
            } else {
                // 添加新任务
                RlTask newTask = TaskTransfer.INSTANCE.toRlTask(item);
                // TODO: 2023/6/4 设置用户一致性
                newTask = this.fixIdAndName(newTask);
                this.saveDispatchTask(newTask);

            }
        });
        Date end = new Date();
        log.info("执行时长：" + (end.getTime() - start.getTime()) + "ms，" + "轮询数据：" + meetings.size() + "条");
    }

    /**
     * 轮询提醒
     *
     * @throws Exception
     */
    @Scheduled(cron = "0 * * * * ?")
    public void remindUserInfo() throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date date = DateUtil.date();
        // 查询当天日程，isRepeat表示是否提醒
        List<RlSchedule> scheduleList = iRlScheduleService.lambdaQuery()
                .eq(RlSchedule::getDelFlag, DelEnum.True.getCode())
                .ne(RlSchedule::getIsRepeat, EnabledEnum.False.getCode())
                .between(RlSchedule::getBeginTime, DateUtil.beginOfDay(date), DateUtil.endOfDay(date))
                .list();
        for (RlSchedule item : scheduleList) {
            // 提前30分钟
            Date remindTime = DateUtil.offsetMinute(item.getBeginTime(), -30);
            if (DateUtil.format(remindTime, sdf).equals(DateUtil.format(DateUtil.date(), sdf))) {
//                dingDingService.remindUser(item);
                log.info("日程id：{}，在{}进行提醒", item.getId(), item.getBeginTime());
            }
        }
    }


    /**
     * 通过OA用户表，修复缺失的用户信息及缺少工号的钉钉用户
     *
     * @param task
     * @return
     */
    private RlTask fixIdAndName(RlTask task) {
        // 发送人id和姓名
        HrmResource sender = iHrmResourceService.lambdaQuery()
                .eq(HrmResource::getId, task.getUserId())
                .one();
        // 初始化参数，设置发送方，防止空指针
        String lastname;
        String userId = null;
        String workCode;
        String departId;
        String departName;
        try {
            lastname = sender.getLastname();
            workCode = sender.getWorkcode();
            SysUser sysUser = iSysUserService.lambdaQuery()
                    .eq(SysUser::getWorkNo, workCode)
                    .one();
            userId = sysUser.getId();
            departId = sysUser.getDepartIds();
            departName = iSysDepartService.lambdaQuery()
                    .eq(SysDepart::getId, departId)
                    .one().getDepartName();
        } catch (NullPointerException e) {
            log.info("时间：" + DateUtil.today() + "，用户{}信息缺失，当前轮询数据跳过！", userId);
            return null;
        }
        // 初始化参数，设置接收方，防止空指针
        List<String> recipientIds = new ArrayList<>();
        List<String> recipientNames = new ArrayList<>();
        String newIds;
        String newNames;
        List<String> oaIds = Convert.toList(String.class, task.getRecipientId());
        // 等于0表示接收人为空
        if (oaIds.size() != '0') {
            // 接收人id和姓名
            for (String item : oaIds) {
                SysUser user;
                String oneRecipientId;
                String oneRecipientName;
                try {
                    String oaWorkCode = iHrmResourceService.lambdaQuery()
                            .eq(HrmResource::getId, item)
                            .one().getWorkcode();
                    user = iSysUserService.lambdaQuery()
                            .eq(SysUser::getWorkNo, oaWorkCode)
                            .one();
                    oneRecipientId = user.getId();
                    oneRecipientName = user.getRealname();
                } catch (NullPointerException e) {
                    log.info("信息缺失，当前轮询数据跳过！");
                    return null;
                }
                recipientIds.add(oneRecipientId);
                recipientNames.add(oneRecipientName);
            }
        }
        newIds = TaskTransfer.list2String(recipientIds);
        newNames = TaskTransfer.list2String(recipientNames);

        task.setUserId(userId)
                .setUserName(lastname)
                .setRecipientId(newIds)
                .setRecipientName(newNames)
                .setDepId(departId)
                .setDepName(departName);
        return task;
    }


    /**
     * 设置时间，根据开始时间进行排序
     *
     * @param userTask
     * @return
     */
    public List<QueryTaskVO> splitDate(List<RlTask> userTask) {
        // 切割时间
        List<QueryTaskVO> userTaskVo = TaskTransfer.INSTANCE.toQueryTask(userTask);
        userTaskVo.forEach(item -> {
            item.setBeginDate(DateUtil.format(item.getBeginTime(), "yyyy-MM-dd"));
            item.setBeginDateTime(DateUtil.format(item.getBeginTime(), "HH:mm"));
            item.setEndDate(DateUtil.format(item.getEndTime(), "yyyy-MM-dd"));
            item.setEndDateTime(DateUtil.format(item.getEndTime(), "HH:mm"));
        });
        return userTaskVo.stream()
                .sorted(Comparator.comparing(QueryTaskVO::getBeginTime).reversed()).collect(Collectors.toList());

    }

    /**
     * @param dto
     * @return
     */
    @Override
    public PageData<QueryTaskVO> queryDispatchTask(QueryTaskDto dto) {
        LambdaQueryWrapper<RlTask> wrapper = new LambdaQueryWrapper<>();
        // 不能这么写wrapper.ge(ObjectUtil.isNotEmpty(dto.getStartTime(), RlTask::getBeginTime, DateUtil.beginOfDay(dto.getStartTime()))，会预处理真是坑死人
        if (ObjectUtil.isNotEmpty(dto.getStartTime())) {
            wrapper.ge(RlTask::getBeginTime, DateUtil.beginOfDay(dto.getStartTime()));
        }
        if (ObjectUtil.isNotEmpty(dto.getEndTime())) {
            wrapper.le(RlTask::getEndTime, DateUtil.endOfDay(dto.getEndTime()));
        }
        wrapper.eq(RlTask::getUserId, dto.getUserId())
                .eq(RlTask::getDelFlag, DelEnum.True.getCode())
                .orderByDesc(RlTask::getBeginTime);
        // 枚举类乱了已经
        if (dto.getStatus().equals(QueryEnum.UNREAD_SCHEDULE.getCode())) {
            wrapper.eq(RlTask::getIsComplete, CompleteEnum.UNREAD.getCode());
        } else if (dto.getStatus().equals(QueryEnum.NOT_COMPLETED_SCHEDULE.getCode())) {
            wrapper.in(RlTask::getIsComplete, Arrays.asList(CompleteEnum.READ.getCode(), CompleteEnum.OVERTIME.getCode()));
        } else if (dto.getStatus().equals(QueryEnum.COMPLETED_SCHEDULE.getCode())) {
            wrapper.eq(RlTask::getIsComplete, CompleteEnum.FINISH.getCode());
        } else {
            String isComplete = dto.getStatus();
            wrapper.eq(StrUtil.isNotBlank(isComplete), RlTask::getIsComplete, isComplete);
        }

        Page<RlTask> page = this.page(dto.getPage(), wrapper);

        List<RlTask> tmpList = page.getRecords();
        // 更新数据状态
        this.queryTaskFilter(tmpList);

        // 改字段
        List<QueryTaskVO> voList = new ArrayList<>();
        if (CollUtil.isNotEmpty(tmpList)) {
            voList = this.splitDate(tmpList);
            voList.forEach(e -> e.setFilePath(this.convertFilePath(e.getFilePath())));
        }
        return PageData.convertPageData(page, voList);
    }

    public void queryTaskFilter(List<RlTask> list) {
        for (RlTask task : list) {
            String[] scheduleList = task.getRecipientTaskId().split(",");
            boolean FINISH = Boolean.FALSE;
            boolean UNREAD = Boolean.FALSE;
            for (String scheduleId : scheduleList) {
                String isComplete = iRlScheduleService.lambdaQuery().eq(RlSchedule::getId, scheduleId).one().getIsComplete();
                if (isComplete.equals(CompleteEnum.FINISH.getCode()) ||
                        isComplete.equals(CompleteEnum.ARCHIVE.getCode())) {
                    FINISH = Boolean.TRUE;
                    // 已读状态
                } else if (isComplete.equals(CompleteEnum.READ.getCode())) {
                    this.lambdaUpdate().eq(RlTask::getId, task.getId())
                            .set(RlTask::getIsComplete, CompleteEnum.READ.getCode())
                            .update();
                    break;
                    // 超时状态
                } else if (isComplete.equals(CompleteEnum.OVERTIME.getCode())) {
                    this.lambdaUpdate().eq(RlTask::getId, task.getId())
                            .set(RlTask::getIsComplete, CompleteEnum.OVERTIME.getCode())
                            .update();
                    break;
                } else if (isComplete.equals(CompleteEnum.UNREAD.getCode())) {
                    UNREAD = Boolean.TRUE;
                }
            }
            // 完成和未查收
            if (FINISH == (Boolean.TRUE) && UNREAD == (Boolean.FALSE)) {
                this.lambdaUpdate().eq(RlTask::getId, task.getId())
                        .set(RlTask::getIsComplete, CompleteEnum.FINISH.getCode())
                        .update();
            } else if (FINISH == (Boolean.FALSE) && UNREAD == (Boolean.TRUE)) {
                this.lambdaUpdate().eq(RlTask::getId, task.getId())
                        .set(RlTask::getIsComplete, CompleteEnum.UNREAD.getCode())
                        .update();
            }
        }
    }

    /**
     * 上传文件，源代码在Common Controller
     *
     * @param file
     */
 /*   public String uploadFile(MultipartFile file) throws Exception {
        String savePath = "";
        String bizPath = "";

        //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞
        if (oConvertUtils.isNotEmpty(bizPath)) {
            if (bizPath.contains(SymbolConstant.SPOT_SINGLE_SLASH) || bizPath.contains(SymbolConstant.SPOT_DOUBLE_BACKSLASH)) {
                throw new JeecgBootException("上传目录bizPath，格式非法！");
            }
        }


//        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
//        // 获取上传文件对象
//        MultipartFile file = multipartRequest.getFile("file");
        if (oConvertUtils.isEmpty(bizPath)) {
            if (CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)) {
                //未指定目录，则用阿里云默认目录 upload
                bizPath = "upload";
                //result.setMessage("使用阿里云文件上传时，必须添加目录！");
                //result.setSuccess(false);
                //return result;
            } else {
                bizPath = "";
            }
        }
        if (CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)) {
            //update-begin-author:liusq date:20221102 for: 过滤上传文件类型
            FileTypeFilter.fileTypeFilter(file);
            //update-end-author:liusq date:20221102 for: 过滤上传文件类型
            //update-begin-author:lvdandan date:20200928 for:修改JEditor编辑器本地上传
            savePath = this.uploadLocal(file, bizPath);
            //update-begin-author:lvdandan date:20200928 for:修改JEditor编辑器本地上传
            *//**  富文本编辑器及markdown本地上传时，采用返回链接方式
             //针对jeditor编辑器如何使 lcaol模式，采用 base64格式存储
             String jeditor = request.getParameter("jeditor");
             if(oConvertUtils.isNotEmpty(jeditor)){
             result.setMessage(CommonConstant.UPLOAD_TYPE_LOCAL);
             result.setSuccess(true);
             return result;
             }else{
             savePath = this.uploadLocal(file,bizPath);
             }
             *//*
        } else {
            //update-begin-author:taoyan date:20200814 for:文件上传改造
            savePath = CommonUtils.upload(file, bizPath, uploadType);
            //update-end-author:taoyan date:20200814 for:文件上传改造
        }
        if (oConvertUtils.isEmpty(savePath)) {
            throw new JeecgBootException("文件上传失败！");
        }
        return savePath;
    }*/

    /**
     * 本地文件上传
     *
     * @param mf      文件
     * @param bizPath 自定义路径
     * @return
     */
    private String uploadLocal(MultipartFile mf, String bizPath) {
        try {
            String ctxPath = uploadpath;
            String fileName = null;
            File file = new File(ctxPath + File.separator + bizPath + File.separator);
            if (!file.exists()) {
                // 创建文件根目录
                file.mkdirs();
            }
            // 获取文件名
            String orgName = mf.getOriginalFilename();
            orgName = CommonUtils.getFileName(orgName);
            if (orgName.indexOf(SymbolConstant.SPOT) != -1) {
                fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
            } else {
                fileName = orgName + "_" + System.currentTimeMillis();
            }
            String savePath = file.getPath() + File.separator + fileName;
            File savefile = new File(savePath);
            FileCopyUtils.copy(mf.getBytes(), savefile);
            String dbpath = null;
            if (oConvertUtils.isNotEmpty(bizPath)) {
                dbpath = bizPath + File.separator + fileName;
            } else {
                dbpath = fileName;
            }
            if (dbpath.contains(SymbolConstant.DOUBLE_BACKSLASH)) {
                dbpath = dbpath.replace(SymbolConstant.DOUBLE_BACKSLASH, SymbolConstant.SINGLE_SLASH);
            }
            return dbpath;
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        return "";
    }

    /**
     * 任务转日程默认属性
     *
     * @param task
     * @return
     */
    public RlSchedule setDefaultSchedule(RlTask task) {
        RlSchedule schedule = TaskTransfer.INSTANCE.onlySchedule(task);
        // 设置完成-未读
        schedule.setIsComplete(CompleteEnum.UNREAD.getCode());
        // 设置状态-任务
        schedule.setState(StateEnum.TASK.getCode());
        // 设置程度-重要
        if (StrUtil.isBlank(task.getLevel())) {
            schedule.setLevel(LevalEnum.IMPORTANT.getCode());
        }
        // 设置启用
        schedule.setDelFlag(DelEnum.True.getCode());
        return schedule;
    }

    /**
     * 添加任务，在日程中也添加
     *
     * @param task
     */
    @Transactional(rollbackFor = Exception.class)
    // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    @Override
    public void saveDispatchTask(RlTaskSaveDto task) {
        RlTask rlTask = TaskTransfer.INSTANCE.toEntity(task);

        // 设置文件名及路径
        rlTask.setFileName(task.getFileName());
        rlTask.setFilePath(uploadpath + task.getFilePath());

        // 设置默认启动
        rlTask.setDelFlag(DelEnum.True.getCode());
        if (StrUtil.isBlank(task.getRemind())) {
            task.setIsComplete(EnabledEnum.False.getCode());
        }
        List<String> userIds = task.getRecipientId();
        RlSchedule schedule = this.setDefaultSchedule(rlTask);
        // 初始化关联任务id
        List<Integer> scheduleIdList = new ArrayList<>();
        for (String userId : userIds) {
            // 深拷贝
            RlSchedule scheduleOne = ObjectUtil.cloneByStream(schedule);
            scheduleOne.setUserId(userId);
            scheduleOne.setUserName(iSysUserService.getOne(new LambdaQueryWrapper<SysUser>()
                                                                   .eq(SysUser::getId, userId)).getRealname());
            iRlScheduleService.save(scheduleOne);
            // 添加关联任务
            scheduleIdList.add(scheduleOne.getId());
        }
        rlTask.setRecipientId(TaskTransfer.list2String(userIds));
        rlTask.setRecipientTaskId(TaskTransfer.int2String(scheduleIdList));
        try {
//            String dingId = dingDingService.addTaskToDingDing(rlTask, task.getRemind(), task.getRecurrence());
//            rlTask.setDingId(dingId);
        } catch (Exception e) {
            log.error("时间：" + DateUtil.today() + ",任务{}, 日程同步至钉钉日历异常！", rlTask.getTitle());
        }
        this.save(rlTask);
        iRlScheduleService.lambdaUpdate()
                .in(RlSchedule::getId, Arrays.asList(rlTask.getRecipientTaskId().split(",")))
                .set(RlSchedule::getTaskId, rlTask.getId()).update();
    }


    /**
     * 添加任务，web接口
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveDispatchTaskFromWeb(RlTaskWebSaveDto dto) {
        List<String> userIds = Arrays.asList(dto.getRecipientId().split(","));
        RlTask task = TaskTransfer.INSTANCE.toTask(dto);

        if (ObjectUtil.isNotEmpty(dto.getMultipartFile())) {
            // 获得源文件
            MultipartFile mf = dto.getMultipartFile();
            String fileName;
            String filePath;
            try {
//                filePath = uploadpath + File.separator + this.uploadFile(mf);
                fileName = mf.getOriginalFilename();
            } catch (Exception e) {
                throw new JeecgBootException("文件上传失败！");
            }
            // 设置文件路径
            task.setFileName(fileName);
//            task.setFilePath(filePath);
        }

        RlSchedule schedule = this.setDefaultSchedule(task);
        // 初始化关联任务id
        List<Integer> scheduleIdList = new ArrayList<>();
        for (String userId : userIds) {
            // 深拷贝
            RlSchedule scheduleOne = ObjectUtil.cloneByStream(schedule);
            scheduleOne.setUserId(userId);
            iRlScheduleService.save(scheduleOne);
            // 添加关联任务
            scheduleIdList.add(scheduleOne.getId());
        }
        task.setRecipientId(TaskTransfer.list2String(userIds));
        task.setRecipientTaskId(TaskTransfer.int2String(scheduleIdList));
        try {
//            String dingId = dingDingService.addTaskToDingDing(task, null, null);
//            task.setDingId(dingId);
        } catch (Exception e) {
            log.error("时间：" + DateUtil.today() + ",任务Id{}, 日程同步至钉钉日历异常！", task.getId());
        }
        this.save(task);
        iRlScheduleService.lambdaUpdate()
                .in(RlSchedule::getId, Arrays.asList(task.getRecipientTaskId().split(",")))
                .set(RlSchedule::getTaskId, task.getId()).update();
    }

    /**
     * 修改任务，web接口
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateDispatchTaskFromWeb(RlTaskWebSaveDto dto) {
        RlTask task = TaskTransfer.INSTANCE.toTask(dto);
        RlSchedule schedule = TaskTransfer.INSTANCE.onlySchedule(task);

        if (ObjectUtil.isNotEmpty(dto.getMultipartFile())) {
            // 获得源文件
            MultipartFile mf = dto.getMultipartFile();
            String fileName;
            String filePath;
            try {
//                filePath = uploadpath + File.separator + this.uploadFile(mf);
                fileName = mf.getOriginalFilename();
            } catch (Exception e) {
                throw new JeecgBootException("文件上传失败！");
            }
            // 设置文件路径
            task.setFileName(fileName);
//            task.setFilePath(filePath);
        }

        // 获得接收任务成员日程id
        Integer[] scheduleIdList = Convert.toIntArray(this.lambdaQuery()
                                                              .eq(RlTask::getId, task.getId())
                                                              .one()
                                                              .getRecipientTaskId());
        // 设置完成-未读
        schedule.setIsComplete(CompleteEnum.UNREAD.getCode());
        for (Integer scheduleId : scheduleIdList) {
            // 深拷贝
            RlSchedule scheduleOne = ObjectUtil.cloneByStream(schedule);
            scheduleOne.setId(scheduleId);
            iRlScheduleService.updateById(scheduleOne);
        }
        try {
//            dingDingService.updateById(task, null, null);
        } catch (Exception e) {
            log.error("时间：{}，" + "修改任务异常id{}", DateUtil.today(), task.getId());
            throw new JeecgBootException("同步钉钉日历失败！");
        }
        this.updateById(task);
    }

    /**
     * 轮询oa数据
     *
     * @param task
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveDispatchTask(RlTask task) {
        if (ObjectUtil.isNotEmpty(task)) {
            List<String> userIds = Arrays.asList(Convert.toStrArray(task.getRecipientId()));
            RlSchedule schedule = TaskTransfer.INSTANCE.toSchedule(task);

            // 初始化关联任务id
            List<Integer> scheduleIdList = new ArrayList<>();
            for (String userId : userIds) {
                // 深拷贝
                RlSchedule scheduleOne = ObjectUtil.cloneByStream(schedule);
                scheduleOne.setUserId(userId);
                scheduleOne.setUserName(iSysUserService.lambdaQuery().eq(SysUser::getId, userId).one().getRealname());
                iRlScheduleService.save(scheduleOne);
                // 添加关联任务
                scheduleIdList.add(scheduleOne.getId());
            }
            task.setRecipientId(TaskTransfer.list2String(userIds));
            task.setRecipientTaskId(TaskTransfer.int2String(scheduleIdList));
            try {
//                String dingId = dingDingService.addTaskToDingDing(task, null, null);
//                task.setDingId(dingId);
            } catch (Exception e) {
                log.error("时间：" + DateUtil.today() + ",任务Id{}, 日程同步至钉钉日历异常！", task.getId());
            }
            this.save(task);
            iRlScheduleService.lambdaUpdate()
                    .in(RlSchedule::getId, Arrays.asList(task.getRecipientTaskId().split(",")))
                    .set(RlSchedule::getTaskId, task.getId()).update();
        }
    }

    /**
     * 修改任务，同时修改接受成员日程数据，默认未读
     *
     * @param taskDto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateDispatchTask(TaskUpdateDto taskDto) {
        this.revokeUserTask(taskDto.getId());
        RlTaskSaveDto task = TaskTransfer.INSTANCE.updateToSave(taskDto);
        task.setId(null).setDingId(null).setIsRepeat("").setIsHoliday("").setIsWeekend("")
                .setIsComplete("").setState(StateEnum.TASK.getCode()).setDelFlag(EnabledEnum.False.getCode());
        this.saveDispatchTask(task);
//        // 设置文件名及路径
//        task.setFileName(task.getFileName());
//        task.setFilePath(uploadpath + File.separator + task.getFilePath());
//
//        RlSchedule schedule = TaskTransfer.INSTANCE.onlySchedule(task);
//        // 获得接收任务成员日程id
//        Integer[] scheduleIdList = Convert.toIntArray(this.lambdaQuery()
//                .eq(RlTask::getId, task.getId())
//                .one()
//                .getRecipientTaskId());
//        if (StrUtil.isBlank(taskDto.getRemind())) {
//            task.setIsRepeat(EnabledEnum.False.getCode());
//        }
//        // 设置完成-未读
//        schedule.setIsComplete(CompleteEnum.UNREAD.getCode());
//        for (Integer scheduleId : scheduleIdList) {
//            // 深拷贝
//            RlSchedule scheduleOne = ObjectUtil.cloneByStream(schedule);
//            scheduleOne.setId(scheduleId);
//            iRlScheduleService.updateById(scheduleOne);
//        }
//        try {
//            String dingId = dingDingService.updateById(task, taskDto.getRemind(), taskDto.getRecurrence());
//            task.setDingId(dingId);
//        } catch (Exception e) {
//            log.error("时间：{}，" + "修改任务异常id{}", DateUtil.today(), task.getId());
//            throw new JeecgBootException("同步钉钉日历失败！");
//        }
//        this.updateById(task);
    }


    @Override
    public List<QueryTaskVO> queryUserTask(QueryTaskUserDto dto) {
        // 这块的意思是查看符合条件的task，再查看对应日程的状态，修改list中的状态进行展示
        String id = dto.getUserId();
        List<RlTask> list = this.lambdaQuery()
                .like(RlTask::getRecipientId, id)
//                .ge(RlTask::getEndTime, DateUtil.beginOfDay(DateUtil.date()))
                .like(StrUtil.isNotBlank(dto.getTitle()), RlTask::getTitle, dto.getTitle())
                .list();

        // 查看完成状态应该根据schedule表进行
        for (int i = 0, len = list.size(); i < len; i++) {
            String[] idList = list.get(i).getRecipientId().split(",");
            String[] scheduleList = list.get(i).getRecipientTaskId().split(",");
            String[] schedulerList = list.get(i).getRecipientId().split(",");
            for (int j = 0; j < idList.length; j++) {
                if (idList[j].equals(dto.getUserId())) {
                    String scheduleId = scheduleList[j];
                    String schedulerId = schedulerList[j];
                    list.get(i).setIsComplete(iRlScheduleService.lambdaQuery()
                                                      .eq(RlSchedule::getId, scheduleId)
                                                      .one().getIsComplete())
                            .setScheduleId(scheduleId)
                            .setScheduleUserId(schedulerId);
                    break;
                }
            }
        }
        List<QueryTaskVO> result = this.splitDate(list);
        result.forEach(e -> e.setFilePath(this.convertFilePath(e.getFilePath())));
        return result;
    }

    @Override
    public void modifyTaskState(ModifyStateDto dto) {
        // 获取对象
        RlTask task = this.lambdaQuery()
                .eq(RlTask::getId, dto.getTaskId())
                .one();

        // 匹配scheduleId
        String[] idList = task.getRecipientId().split(",");
        String[] scheduleIdList = task.getRecipientTaskId().split(",");
        for (int i = 0; i < idList.length; i++) {
            // 匹配成功修改状态
            if (idList[i].equals(dto.getUserId())) {
                String scheduleId = scheduleIdList[i];
                iRlScheduleService.lambdaUpdate()
                        .eq(RlSchedule::getId, scheduleId)
                        .set(RlSchedule::getIsComplete, dto.getIsComplete())
                        .update();
                break;
            }
        }

    }

    @Override
    public List<SysUser> queryAllUser(QueryUserDto dto) {
        return iSysUserService.lambdaQuery()
                .like((StrUtil.isNotBlank(dto.getContext())), SysUser::getUsername, dto.getContext())
                .list();
    }

    /**
     * 撤回任务
     *
     * @param id
     */
    @Override
    public void revokeUserTask(Integer id) {
        RlTask task = this.lambdaQuery()
                .eq(RlTask::getId, id)
                .one();
        String recipientTaskId = task.getRecipientTaskId();
        String dingId = task.getDingId();



        iRlScheduleService.lambdaUpdate()
                .set(RlSchedule::getDelFlag, DelEnum.False.getCode())
                .in(RlSchedule::getId, Arrays.asList(recipientTaskId.split(",")))
                .update();

        try {
//            dingDingService.removeById(unionId, dingId);
        } catch (Exception e) {
            log.error("时间：" + DateUtil.today() + "，撤回日程id{}失败！", task.getId());
        }
        this.lambdaUpdate()
                .set(RlTask::getDelFlag, DelEnum.False.getCode())
                .eq(RlTask::getId, id)
                .update();
    }

    /**
     * "统计任务状态"
     *
     * @param id
     * @return
     */
    @Override
    public TaskCompletedVO countTaskState(String id) {
        TaskCompletedVO result = new TaskCompletedVO();

        Long sent = this.lambdaQuery()
                .eq(RlTask::getUserId, id)
                .eq(RlTask::getDelFlag, DelEnum.True.getCode())
                .count();

        Long meeting = iRlScheduleService.lambdaQuery()
                .eq(RlSchedule::getUserId, id)
                .eq(RlSchedule::getIsOa, EnabledEnum.True.getCode())
                .eq(RlSchedule::getDelFlag, DelEnum.True.getCode())
                .count();

        Long unread = iRlScheduleService.lambdaQuery()
                .eq(RlSchedule::getUserId, id)
                .eq(RlSchedule::getIsComplete, CompleteEnum.UNREAD.getCode())
                .eq(RlSchedule::getDelFlag, DelEnum.True.getCode())
                .count();

        Long read = iRlScheduleService.lambdaQuery()
                .eq(RlSchedule::getUserId, id)
                .eq(RlSchedule::getIsComplete, CompleteEnum.READ.getCode())
                .eq(RlSchedule::getDelFlag, DelEnum.True.getCode())
                .count();

        Long finish = iRlScheduleService.lambdaQuery()
                .eq(RlSchedule::getUserId, id)
                .eq(RlSchedule::getDelFlag, DelEnum.True.getCode())
                .and(e -> e.eq(RlSchedule::getIsComplete, CompleteEnum.FINISH.getCode())
                        .or()
                        .eq(RlSchedule::getIsComplete, CompleteEnum.ARCHIVE.getCode()))
                .count();

        Long overtime = iRlScheduleService.lambdaQuery()
                .eq(RlSchedule::getUserId, id)
                .eq(RlSchedule::getIsComplete, CompleteEnum.OVERTIME.getCode())
                .eq(RlSchedule::getDelFlag, DelEnum.True.getCode())
                .count();


        String realname;
        try {
            realname = iSysUserService.lambdaQuery()
                    .eq(SysUser::getId, id)
                    .one().getRealname();
        } catch (NullPointerException e) {
            realname = "";
        }

        result.setUnread(unread)
                .setRead(read)
                .setFinish(finish)
                .setSent(sent)
                .setId(id)
                .setUsername(realname)
                .setMeeting(meeting)
                .setOvertime(overtime);
        return result;
    }

    /**
     * 修补用户信息，部分用户钉钉的workno为空，系统会自动填充，此处根据用户表的workno进行update
     * 部分未导入钉钉用户根据用户表的loginid进行生成
     */
    @Override
    public void fixUserInfo() {
       /* List<SysUser> list = iSysUserService.lambdaQuery().list();

        // 去除同名用户
        for (SysUser i : list) {
            for (SysUser j : list) {
                if (i.getRealname().equals(j.getRealname()) && !i.getId().equals(j.getId())) {
                    if (StrUtil.isBlank(i.getUnionId()) && i.getCreateBy().equals("OA")) {
                        sysUserMapper.deleteByUserId(i.getId());

                    } else if (StrUtil.isBlank(j.getUnionId()) && i.getCreateBy().equals("OA")) {
                        sysUserMapper.deleteByUserId(j.getId());
                    }
                }
            }
        }

        list = iSysUserService.lambdaQuery().list();
        List<HrmResource> hrList = iHrmResourceService.qureyEnableUserList();
        for (HrmResource resource : hrList) {
            boolean flag = true;
            for (SysUser user : list) {
                if (user.getWorkNo().equals(resource.getWorkcode()) && user.getRealname().equals(resource.getLastname())) {
                    flag = false;
                    break;
                } else if ((!user.getWorkNo().equals(resource.getWorkcode())) && user.getRealname().contains(resource.getLastname())) {
                    // 更新工号
                    iSysUserService.lambdaUpdate()
                            .eq(SysUser::getRealname, user.getRealname())
                            .set(SysUser::getWorkNo, resource.getWorkcode())
                            .update();
                    flag = false;
                    break;
                }
            }

            // OA表匹配，生成OA表中没有同步过来的用户
            List<String> workNoList = list.stream().map(SysUser::getWorkNo).collect(Collectors.toList());
            if (flag && StrUtil.isNotBlank(resource.getLoginid())) {
                if (workNoList.contains(resource.getWorkcode())) {
                    break;
                }
                User user = new User();
                // 这里用mobile是设置了转换，mobile转用户的userid
                user.setMobile(resource.getLoginid());
                user.setName(resource.getLastname());
                user.setJob_number(resource.getWorkcode());
                SysUser sysUser = thirdAppDingtalkService.dtUserToSysUser(user);
                sysUser.setCreateBy("OA");
                iSysUserService.save(sysUser);
            }
        }


        // 修复OA同步用户部门信息缺失
        List<SysUser> userList = iSysUserService.lambdaQuery().list();
        String filePath = "人员资料0905.xlsx"; // 替换为您的Excel文件路径

        try (FileInputStream fis = new FileInputStream(filePath);
             Workbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(0); // 假设要读取第一个工作表

            boolean firstRow = true;
            for (Row row : sheet) {
                // 跳过第一行
                if (firstRow) {
                    firstRow = false;
                    continue;
                }
                // 名称，部门
                userDepartVO userDepart = new userDepartVO(row.getCell(0).getStringCellValue(), row.getCell(1).getStringCellValue());

                // 筛选是否需要更新
                long count = userList.stream()
                        .filter(e -> (StrUtil.isEmpty(e.getUnionId()) && e.getRealname().equals(userDepart.getName()) && StrUtil.isEmpty(e.getDepartIds())))
                        .count();
                if (count == 1) {
                    String[] departSplit = userDepart.getDepart().split("-");
                    // 长度从1开始计算，分割后长度为2，说明有两个部门
                    if (departSplit.length > 1) {
                        SysDepart firstDepart = iSysDepartService.lambdaQuery().eq(SysDepart::getDepartName, departSplit[0]).one();
                        if (firstDepart == null) {
                            continue;
                        }
                        SysDepart secondDepart = iSysDepartService.lambdaQuery().eq(SysDepart::getDepartName, departSplit[1])
                                .eq(SysDepart::getParentId, firstDepart.getId()).one();
                        if (secondDepart != null) {
                            Optional<SysUser> optionalUser = userList.stream().filter(e -> e.getRealname().equals(userDepart.getName())).findFirst();
                            if (!optionalUser.isPresent()) {
                                continue;
                            }
                            // 删除关联表原数据再添加
                            SysUser sysUser = optionalUser.get();
                            sysUser.setDepartIds(secondDepart.getId());
                            iSysUserService.updateById(sysUser);
                            iSysUserDepartService.remove(new LambdaQueryWrapper<SysUserDepart>()
                                                                 .eq(SysUserDepart::getUserId, sysUser.getId()));
                            iSysUserDepartService.save(new SysUserDepart(sysUser.getId(), secondDepart.getId()));
                            iSysUserDepartService.save(new SysUserDepart(sysUser.getId(), firstDepart.getId()));
                        }
                    } else {
                        SysDepart firstDepart = iSysDepartService.lambdaQuery().eq(SysDepart::getDepartName, departSplit[0]).one();
                        if (firstDepart != null) {
                            Optional<SysUser> optionalUser = userList.stream().filter(e -> e.getRealname().equals(userDepart.getName())).findFirst();
                            if (!optionalUser.isPresent()) {
                                continue;
                            }
                            SysUser sysUser = optionalUser.get();
                            sysUser.setDepartIds(firstDepart.getId());
                            iSysUserService.updateById(sysUser);
                            iSysUserDepartService.remove(new LambdaQueryWrapper<SysUserDepart>()
                                                                 .eq(SysUserDepart::getUserId, sysUser.getId()));
                            iSysUserDepartService.save(new SysUserDepart(sysUser.getId(), firstDepart.getId()));
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }*/
    }

    @Override
    public List<UserTreeVO> queryUserByDepart() {
        // orgType: 1-一级部门
        List<SysDepart> orgCodeList = iSysDepartService.lambdaQuery()
                .eq(SysDepart::getOrgType, "1")
                .orderBy(true, true, SysDepart::getDepartOrder)
                .list();

        List<UserTreeVO> result = new ArrayList<>();
        for (SysDepart depart : orgCodeList) {
            List<String> departIds = iSysDepartService.lambdaQuery()
                    .likeRight(SysDepart::getOrgCode, depart.getOrgCode())
                    .list().stream()
                    .map(SysDepart::getId).collect(Collectors.toList());

            // TODO: 2023/8/31 多部门时无法对其进行选择 
            List<SysUser> userList = iSysUserService.lambdaQuery()
                    .in(SysUser::getDepartIds, departIds)
                    .orderBy(true, true, SysUser::getUserIdentity)
                    .list();
            List<UserVO> userVOList = new ArrayList<>();
            userList.forEach(e -> userVOList.add(new UserVO(e.getId(), e.getRealname())));
            UserTreeVO treeVO = new UserTreeVO();
            treeVO.setId(depart.getId())
                    .setName(depart.getDepartName())
                    .setUserList(userVOList);
            result.add(treeVO);
        }
        return result;
    }

    @Override
    public IPage<RlTask> queryPageInfo(QueryTaskWebDto dto, Long pageNo, Long pageSize) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        Page<RlTask> page = this.lambdaQuery()
                .like(StrUtil.isNotBlank(dto.getUserName()), RlTask::getUserName, dto.getUserName())
                .like(StrUtil.isNotBlank(dto.getRecipientName()), RlTask::getRecipientName, dto.getRecipientName())
                .le(ObjectUtil.isNotEmpty(dto.getStartTime()), RlTask::getBeginTime, dto.getStartTime())
                .ge(ObjectUtil.isNotEmpty(dto.getEndTime()), RlTask::getEndTime, dto.getEndTime())
                .eq(RlTask::getCreateBy, user.getUsername())
                .orderByDesc(RlTask::getUpdateTime)
                .page(new Page<>(pageNo, pageSize));
        page.getRecords().forEach(e -> e.setFilePath(this.convertFilePath(e.getFilePath())));
        return page;
    }

    /**
     * 转换文件路径
     *
     * @param filePath
     * @return
     */
    @Override
    public String convertFilePath(String filePath) {
        if (StrUtil.isBlank(filePath)) {
            return "";
        }
        // 不知道为啥这里用File.separator会报错
        String[] fileName = filePath.split("/");

        String fileOriginalName = null;
        try {
            fileOriginalName = URLEncoder.encode(fileName[fileName.length - 1], String.valueOf(StandardCharsets.UTF_8));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        return new StringBuilder()
                .append(uploadPrefix)
                .append(fileOriginalName)
                .toString();
    }

    @Override
    public Page<RlTask> queryUserTaskInfo(QueryUserTaskInfoDto dto) {
        if (!dto.getState().equals(QueryEnum.SENT_SCHEDULE.getCode())) {
            throw new JeecgBootException("参数异常！");
        } else {
            return this.lambdaQuery()
                    .eq(RlTask::getUserId, dto.getUserId())
                    .eq(RlTask::getDelFlag, DelEnum.True.getCode())
                    .orderByDesc(RlTask::getCreateTime)
                    .page(new Page<>(dto.getPageNo(), dto.getPageSize()));
        }
    }


    @Override
    public OneTaskVO queryTaskInfo(Integer id) {
        RlTask task = this.lambdaQuery().eq(RlTask::getId, id).one();
        // 转换，和文件路径
        OneTaskVO vo = TaskTransfer.INSTANCE.toVo(task);
        vo.setFilePath(this.convertFilePath(vo.getFilePath()));
        // 设置成员状态
        List<UserCompleteVO> userVoList = new ArrayList<>();
        String[] scheduleIdList = vo.getRecipientTaskId().split(",");
        for (String schedule : scheduleIdList) {
            RlSchedule oneSchedule = iRlScheduleService.lambdaQuery().eq(RlSchedule::getId, schedule).one();
            UserCompleteVO userVo = TaskTransfer.INSTANCE.toUserVo(oneSchedule);
            for (CompleteEnum completeEnum : CompleteEnum.values()) {
                System.out.println(completeEnum + completeEnum.getCode());
                if (completeEnum.getCode().equals(userVo.getIsComplete())) {
                    userVo.setIsCompleteText(completeEnum.getMsg());
                    userVoList.add(userVo);
                    break;
                }
            }

        }
        // 根据状态分类
        Map<String, List<UserCompleteVO>> userMap = userVoList.stream()
                .collect(Collectors.groupingBy(UserCompleteVO::getIsCompleteText));
        vo.setUserMap(userMap);
        return vo;
    }

    /**
     * @return
     */
    @Override
    public List<UserTreeSecondVO> queryUserByDeparts() {
        List<UserTreeSecondVO> result = new ArrayList<>();
        List<SysDepart> departList = iSysDepartService.lambdaQuery().eq(SysDepart::getOrgType, "1")
                .orderBy(true, true, SysDepart::getDepartOrder)
                .list();
        for (SysDepart depart : departList) {
            if (depart.getId().equals("658928792")) {
                System.out.println("debug");
            }
            // 二级部门
            if (depart.getDepartName().contains("管理中心")) {
                // 创建管理中心的对象
                UserTreeSecondVO userDepart = new UserTreeSecondVO();
                userDepart.setId(depart.getId()).setName(depart.getDepartName()).setIsDepart("1");
                List<SysDepart> secondDepartList = iSysDepartService.lambdaQuery()
                        .eq(SysDepart::getParentId, depart.getId())
                        .orderBy(true, true, SysDepart::getDepartOrder).list();

                // 管理中心的子类
                List<UserTreeSecondVO> allSecondList = new ArrayList<>();

                if (CollUtil.isNotEmpty(secondDepartList)) {
                    // 先添加领导用户
                    List<SysUser> leaderUser = iSysUserService.lambdaQuery().eq(SysUser::getDepartIds, depart.getId())
                            .in(SysUser::getUserIdentity, Arrays.asList(0, 1, 2, 3))
                            .list();
                    leaderUser.sort(Comparator.comparing(SysUser::getUserIdentity));
                    List<UserTreeSecondVO> leaderUserList = this.convertUser(leaderUser);
                    allSecondList.addAll(leaderUserList);
                    for (SysDepart sysDepart : secondDepartList) {
                        // 二级部门对象
                        UserTreeSecondVO secondTree = new UserTreeSecondVO().setIsDepart("1");
                        List<String> userList = new ArrayList<>();
                        // 流获取符合条件用户id
                        List<SysUserDepart> sysDepartInfo = iSysUserDepartService.lambdaQuery()
                                .eq(SysUserDepart::getDepId, sysDepart.getId()).list();
                        if (CollUtil.isNotEmpty(sysDepartInfo)) {
                            userList = sysDepartInfo.stream().map(SysUserDepart::getUserId).collect(Collectors.toList());
                        } else {
                            continue;
                        }
                        // 成员信息
                        List<SysUser> collect = iSysUserService.lambdaQuery().in(SysUser::getId, userList).list()
                                .stream().sorted(Comparator.comparing(SysUser::getUserIdentity))
                                .collect(Collectors.toList());
                        // 对象转换
                        List<UserTreeSecondVO> departUserList = this.convertUser(collect);
                        secondTree.setId(sysDepart.getId()).setName(sysDepart.getDepartName()).setUserList(departUserList);
                        // 再添加下属部门用户
                        allSecondList.add(secondTree);
//                        // 成员信息
//                        List<SysUser> allUser = iSysUserService.lambdaQuery().in(SysUser::getId, userList).list();
//                        // 分类，二级部门需要根据职级分
//                        Map<Boolean, List<SysUser>> partitionUser = allUser.stream().collect(Collectors.partitioningBy(
//                                e -> e.getUserIdentity() == 0 || e.getUserIdentity() == 1 || e.getUserIdentity() == 2
//                        ));
//                        List<SysUser> leaderUser = partitionUser.get(true);
//                        List<SysUser> normalUser = partitionUser.get(false);
//                        leaderUser.sort(Comparator.comparing(SysUser::getUserIdentity));
//                        normalUser.sort(Comparator.comparing(SysUser::getUserIdentity));
//                        // 对象转换
//                        List<UserTreeSecondVO> departUserList = this.convertUser(normalUser);
//                        List<UserTreeSecondVO> leaderUserList = this.convertUser(leaderUser);
//                        secondTree.setId(sysDepart.getId()).setName(sysDepart.getDepartName()).setUserList(departUserList);
//
//                        allSecondList.addAll(leaderUserList);
//                        allSecondList.add(secondTree);
                    }
                } else {
                    // 避免管理中心部门下无子部门，类比一级部门
                    UserTreeSecondVO noChildDepart = new UserTreeSecondVO().setIsDepart("1");
                    // 部门下的成员
                    List<String> userList = iSysUserDepartService.lambdaQuery()
                            .eq(SysUserDepart::getDepId, depart.getId()).list()
                            .stream().map(SysUserDepart::getUserId).collect(Collectors.toList());
                    // 成员信息
                    List<SysUser> collect = iSysUserService.lambdaQuery().in(SysUser::getId, userList).list()
                            .stream().sorted(Comparator.comparing(SysUser::getUserIdentity))
                            .collect(Collectors.toList());
                    // 对象转换
                    List<UserTreeSecondVO> departUserList = this.convertUser(collect);
                    noChildDepart.setId(depart.getId()).setName(depart.getDepartName()).setUserList(departUserList);
                    result.add(noChildDepart);
                }
                // TODO: 2023/11/20 添加一二级部门 
                userDepart.setUserList(allSecondList);
                result.add(userDepart);
            } else {
                // 一级部门，排序
                UserTreeSecondVO userDepart = new UserTreeSecondVO().setIsDepart("1");
                // 部门下的成员
                List<String> userList = iSysUserDepartService.lambdaQuery()
                        .eq(SysUserDepart::getDepId, depart.getId()).list()
                        .stream().map(SysUserDepart::getUserId).collect(Collectors.toList());
                // 成员信息
                List<SysUser> collect = iSysUserService.lambdaQuery().in(SysUser::getId, userList).list()
                        .stream().sorted(Comparator.comparing(SysUser::getUserIdentity))
                        .collect(Collectors.toList());
                // 对象转换
                List<UserTreeSecondVO> departUserList = this.convertUser(collect);
                userDepart.setId(depart.getId()).setName(depart.getDepartName()).setUserList(departUserList);
                result.add(userDepart);
            }
        }
        return result;
    }

    public List<UserTreeSecondVO> convertUser(List<SysUser> param) {
        List<UserTreeSecondVO> result = new ArrayList<>();
        for (SysUser item : param) {
            UserTreeSecondVO user = new UserTreeSecondVO();
            user.setId(item.getId()).setName(item.getRealname());
            result.add(user);
        }
        return result;
    }
}
